﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using FarseerGames.FarseerPhysics.Factories;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;

namespace Kosmos
{
    public class BallSun : Ball
    {
        private const String _path_ball = "Ball";
        private const float _coef_rayon_attraction = 0.5f;
        private const float cst_mass = (float)(100 * Math.PI) * Ball._percent_mass;


        public BallSun(Game g, Vector2 position, float diameter)
            : base(g)
        {
            Body body =
                BodyFactory.Instance.CreateCircleBody
                (((MyGame)g).Simulator, diameter / 2f,
                (float)((diameter / 2f) * (diameter / 2f) * Math.PI) * _percent_mass * 2f);
            body.Position = position;
            body.IsStatic = false;
            body.LinearDragCoefficient = 0.01f;

            Geom = GeomFactory.Instance.CreateCircleGeom
                (((MyGame)g).Simulator, body, diameter / 2f, 100, 1);
            Geom.Tag = this;

            Console.WriteLine(_coef_rayon_attraction * Geom.Body.Mass);

            Geom.CollisionCategories = getType(Type.SUN);
            _type_ball = Type.SUN;

            Geom.OnCollision += OnCollision;
        }

        protected override Color getColor()
        {
            return new Color(255, 150, 0);//Orange
        }

        //Obtenir la distance pour laquel l'attraction du soleil est active
        protected float distAttraction
        {
            get { return _coef_rayon_attraction * Geom.Body.Mass; }
        }

        //Pour savoir si la balle est sous l'effet d'attraction du soleil
        public bool isInAttraction(Ball b)
        {
            float dist = (float)Math.Sqrt(Math.Pow(b.center.X - centerX, 2) + Math.Pow(b.center.Y - centerY, 2));

            return (dist <= distAttraction);
        }

        public override void Update(GameTime gameTime)
        {
            float cst_mass = (float)(100 * Math.PI) * Ball._percent_mass;

            //Attire toute les balles vers lui
            foreach (Ball b in ((MyGame)Game).Level.ListBall)
            {
                if (b == this) continue;// Pour ne pas s'attiré sois meme

                if (!isInAttraction(b)) continue;

                float angle = (float)Math.Atan2((center.Y - b.centerY), centerX - b.centerX);
                Vector2 vec = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
                vec *= (b.Geom.Body.Mass / cst_mass) * 500 * (gameTime.ElapsedGameTime.Milliseconds / 1000f) * ((MyGame)Game).TimeValue;

                b.Geom.Body.ApplyImpulse(vec);
            }

            base.Update(gameTime);
        }

        //Pour mettre en orbite une balle autour du soleil
        public void MettreEnOrbite(Ball b)
        {
            if (!isInAttraction(b)) return;

            float angle = (float)Math.Atan2(b.centerY - centerY, b.centerX - centerX);

            Vector2 v = new Vector2(-(float)Math.Sin(angle), (float)Math.Cos(angle));

            float dist = (float)Math.Sqrt(Math.Pow(b.centerX - centerX, 2) + Math.Pow(b.centerY - centerY, 2));

            float coef_dist = (float)Math.Pow(1.5, Math.Log(dist / 200f, 2));

            if (dist < 200)
                coef_dist = (float)Math.Pow(1.5, -Math.Log(200f / dist, 2));

            float force = (b.Geom.Body.Mass / cst_mass) * 1000 * coef_dist;
            v *= force;

            b.Geom.Body.ApplyImpulse(v);
        }

    }
}
